package com.bt7274.scheduler;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.bt7274.enums.AssessmentCycleType;
import com.bt7274.mapper.UserRuleMapper;
import com.bt7274.pojo.UserRule;
import com.bt7274.pojo.vo.AssessmentStatisticsVO;
import com.bt7274.pojo.vo.BatchAssessmentResultVO;
import com.bt7274.service.AssessmentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;


/**
 * @BelongsProject: bt7274-back
 * @BelongsPackage: com.bt7274.scheduler
 * @Author: Galland
 * @CreateTime: 2025-06-14
 * @Description: 用户考核定时任务
 * @Version: 1.0
 */

@Slf4j
@Component
@RequiredArgsConstructor
public class AssessmentScheduler {

    private final AssessmentService assessmentService;
    private final UserRuleMapper userRuleMapper;

    /**
     * 每日考核任务 - 每天凌晨2点执行
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void executeDailyAssessment() {
        log.info("开始执行每日考核任务...");

        // 检查是否有每日考核规则
        List<UserRule> dailyRules = userRuleMapper.selectList(
                new QueryWrapper<UserRule>()
                        .eq("is_active", 1)
                        .eq("cycle_days", AssessmentCycleType.DAILY.getDays())
        );

        if (!dailyRules.isEmpty()) {
            BatchAssessmentResultVO result = assessmentService.executeAutoAssessment();
            logAssessmentResult("每日考核", result);
        }
    }

    /**
     * 每周考核任务 - 每周一凌晨3点执行
     */
    @Scheduled(cron = "0 0 3 ? * MON")
    public void executeWeeklyAssessment() {
        log.info("开始执行每周考核任务...");

        List<UserRule> weeklyRules = userRuleMapper.selectList(
                new QueryWrapper<UserRule>()
                        .eq("is_active", 1)
                        .eq("cycle_days", AssessmentCycleType.WEEKLY.getDays())
        );

        if (!weeklyRules.isEmpty()) {
            BatchAssessmentResultVO result = assessmentService.executeAutoAssessment();
            logAssessmentResult("每周考核", result);
        }
    }

    /**
     * 每月考核任务 - 每月1日凌晨4点执行
     */
    @Scheduled(cron = "0 0 4 1 * ?")
    public void executeMonthlyAssessment() {
        log.info("开始执行每月考核任务...");

        List<UserRule> monthlyRules = userRuleMapper.selectList(
                new QueryWrapper<UserRule>()
                        .eq("is_active", 1)
                        .eq("cycle_days", AssessmentCycleType.MONTHLY.getDays())
        );

        if (!monthlyRules.isEmpty()) {
            BatchAssessmentResultVO result = assessmentService.executeAutoAssessment();
            logAssessmentResult("每月考核", result);
        }
    }

    /**
     * 通用考核任务 - 每小时执行一次，检查所有需要考核的规则
     */
    @Scheduled(cron = "0 0 * * * ?")
    public void executeGeneralAssessment() {
        log.debug("检查是否有需要执行的考核任务...");

        try {
            // 这个任务会自动检查所有规则的周期，执行需要考核的用户
            BatchAssessmentResultVO result = assessmentService.executeAutoAssessment();

            if (result.getAssessedUsers() > 0) {
                logAssessmentResult("定时考核", result);
            }
        } catch (Exception e) {
            log.error("执行通用考核任务失败", e);
        }
    }

    /**
     * 考核统计任务 - 每天凌晨5点生成前一天的考核报告
     */
    @Scheduled(cron = "0 0 5 * * ?")
    public void generateAssessmentReport() {
        log.info("开始生成考核统计报告...");

        try {
            LocalDateTime yesterday = LocalDateTime.now().minusDays(1);
            LocalDateTime startTime = yesterday.withHour(0).withMinute(0).withSecond(0);
            LocalDateTime endTime = yesterday.withHour(23).withMinute(59).withSecond(59);

            // 获取昨天的考核统计
            List<AssessmentStatisticsVO> statistics =
                    assessmentService.getAssessmentStatistics(null, startTime, endTime);

            if (!statistics.isEmpty()) {
                log.info("=== 考核统计报告 {} ===", yesterday.toLocalDate());
                for (AssessmentStatisticsVO stat : statistics) {
                    log.info("规则: {}, 考核人数: {}, 通过: {}, 未通过: {}, 通过率: {:.2f}%",
                            stat.getRuleName(),
                            stat.getTotalAssessed(),
                            stat.getPassedCount(),
                            stat.getFailedCount(),
                            stat.getPassRate());
                }
            }

            // TODO: 可以将报告发送给管理员或保存到数据库

        } catch (Exception e) {
            log.error("生成考核统计报告失败", e);
        }
    }

    /**
     * 清理旧考核记录 - 每月1日凌晨6点执行
     */
    @Scheduled(cron = "0 0 6 1 * ?")
    public void cleanOldAssessmentRecords() {
        log.info("开始清理旧考核记录...");

        try {
            // 保留最近6个月的记录
            LocalDateTime sixMonthsAgo = LocalDateTime.now().minusMonths(6);

            // TODO: 实现清理逻辑
            // 可以将旧记录归档或删除

            log.info("旧考核记录清理完成");
        } catch (Exception e) {
            log.error("清理旧考核记录失败", e);
        }
    }

    /**
     * 记录考核结果日志
     */
    private void logAssessmentResult(String taskName, BatchAssessmentResultVO result) {
        log.info("{} 完成 - 总用户: {}, 考核: {}, 通过: {}, 未通过: {}, 豁免: {}, 惩罚: {}, 耗时: {}ms",
                taskName,
                result.getTotalUsers(),
                result.getAssessedUsers(),
                result.getPassedUsers(),
                result.getFailedUsers(),
                result.getExemptedUsers(),
                result.getPenaltiesApplied(),
                result.getDuration());

        if (result.getErrors() != null && !result.getErrors().isEmpty()) {
            log.warn("{} 执行过程中出现错误:", taskName);
            result.getErrors().forEach(error -> log.warn("  - {}", error));
        }
    }
}